home *** CD-ROM | disk | FTP | other *** search
/ Garbo / Garbo.cdr / mac / source / music4c.sit / Music4C Folder / SFConvert folder / AiffTo.c next >
C/C++ Source or Header  |  1990-06-24  |  9KB  |  343 lines

  1. #include    "AIFFType.h"
  2. #include    "SFConvert.h"
  3. #include    <unix.h>
  4. #include    <math.h>
  5. #include    <SANE.h>
  6. #include    "SDtype.h"
  7.  
  8. extern    void    DoOSErrorAlert(Str255, Str255);
  9. extern    void    PstringCopy(char *, char *);
  10. extern    void    PstringCat(char *, char *);
  11. extern    void    DoOSErrorAlert(Str255, Str255);
  12.  
  13. Boolean    AIFFToSD(void);
  14. Boolean    AIFFToINT16(void);
  15. Boolean    AIFFToFloat(void);
  16.  
  17.  
  18. Str255    theMess;
  19.  
  20. extern    CursHandle    watchCurs;
  21. extern    int            SoundFileType;
  22. extern    int            SFOUTPUTtype;
  23. extern    int            nrec;
  24.  
  25. extern    long        TotalSamps;
  26. extern    long        SampleRate;
  27. extern    long        NumChannels;
  28. extern    double        MaxSample;
  29. extern    double        MinSample;
  30. extern    long        fileSize;
  31. extern    ioParam        myIOParmBlk;
  32. extern    ioParam        NewParmBlk;
  33. extern    Boolean        SDnoResource;
  34. extern    OSErr        theErr;
  35. extern    long        RecLength;
  36.  
  37. Boolean    AIFFToSD()
  38. {
  39.     return(FALSE);
  40. }
  41. Boolean    AIFFToINT16()
  42. {
  43.     return(FALSE);
  44. }
  45. Boolean    AIFFToFloat()
  46. {
  47.     register    long    i;
  48.     register    double    scalefactor;
  49.     register    double    x;
  50.     double    peak;
  51.     int        *theIbuf, *Iptr;
  52.     float        *sp, *SampBuf;
  53.     long        nBytes;
  54.     long        nSamps;
  55.     long        bytesLeft;
  56.     long        sampBufsz;
  57.     Chunk        FormChunkHeader, *FormChunkHeaderPtr;
  58.     CommonChunk    CommonHeader, *CommonHeaderPtr;
  59.     SoundDataChunk    SoundDataHeader, *SoundDataHeaderPtr;
  60.     BasicChunk    BaseChunk, *BaseChunkPtr;
  61.     long    aLong, *aLongPtr;
  62.     Boolean        found;
  63.     Fixed    aFix;
  64.     decform    mydecform;
  65.     Str255    myStr255;
  66.  
  67.  
  68.     FormChunkHeaderPtr = &FormChunkHeader;
  69.     CommonHeaderPtr = &CommonHeader;
  70.     SoundDataHeaderPtr = &SoundDataHeader;
  71.  
  72.  
  73.     myIOParmBlk.ioCompletion = 0L;
  74.     myIOParmBlk.ioPosMode = fsFromStart;
  75.     myIOParmBlk.ioPosOffset = 0L;
  76.     theErr = PBSetFPos(&myIOParmBlk, FALSE);
  77.  
  78.  
  79.  
  80.     myIOParmBlk.ioBuffer = (Ptr)FormChunkHeaderPtr;
  81.     myIOParmBlk.ioReqCount = sizeof(FormChunkHeader);
  82.     theErr = PBRead(&myIOParmBlk, FALSE);
  83.     if ( FormChunkHeader.ckID != 'FORM' ) {
  84.         PstringCopy((char *)theMess, "\pError reading AIFF file, FORM header");
  85.         DoOSErrorAlert(theMess, NIL);
  86.         return(FALSE);
  87.     }
  88.  
  89.  
  90.     BaseChunkPtr = &BaseChunk;
  91.     found = FALSE;
  92.  
  93.     while ( !found ) {
  94.         myIOParmBlk.ioBuffer = (Ptr)BaseChunkPtr;
  95.         myIOParmBlk.ioReqCount = sizeof(BaseChunk);
  96.         theErr = PBRead(&myIOParmBlk, FALSE);
  97.         if ( theErr == eofErr ) {
  98.             DoOSErrorAlert("\pError: EOF reading reading AIFF file, no COMM header", NIL);
  99.             return(FALSE);
  100.         }
  101.         if ( BaseChunk.ckID == 'COMM' ) {
  102.             found = TRUE;
  103.             myIOParmBlk.ioPosMode = fsFromMark;
  104.             myIOParmBlk.ioPosOffset = -myIOParmBlk.ioActCount;
  105.             theErr = PBSetFPos(&myIOParmBlk, FALSE);
  106.             myIOParmBlk.ioPosMode = fsAtMark;
  107.         /* get the common chunk info */
  108.             myIOParmBlk.ioBuffer = (Ptr)CommonHeaderPtr;
  109.             myIOParmBlk.ioReqCount = sizeof(CommonHeader);
  110.             theErr = PBRead(&myIOParmBlk, FALSE);
  111.  
  112.             aFix = X2Fix( &CommonHeader.sampleRate);
  113.             SampleRate = (long) aFix;
  114.             mydecform.style = 1;
  115.             mydecform.digits = -1;
  116.             num2str(&mydecform, CommonHeader.sampleRate, &myStr255);
  117.             StringToNum(myStr255, &SampleRate );
  118.  
  119.  
  120.  
  121.  
  122.         }
  123.         else {    /* skip this chunk */
  124.             myIOParmBlk.ioPosMode = fsFromMark;
  125.             myIOParmBlk.ioPosOffset = BaseChunk.ckSize;
  126.             theErr = PBSetFPos(&myIOParmBlk, FALSE);
  127.             if ( theErr == eofErr ) {
  128.                 DoOSErrorAlert("\pError: EOF reading reading AIFF file, no COMM header", NIL);
  129.                 return(FALSE);
  130.             }
  131.             myIOParmBlk.ioPosMode = fsAtMark;
  132.         }
  133.  
  134.     };
  135.  
  136.     /* rewind to start of FORM */
  137.     myIOParmBlk.ioPosMode = fsFromStart;
  138.     myIOParmBlk.ioPosOffset = sizeof(FormChunkHeader);
  139.     theErr = PBSetFPos(&myIOParmBlk, FALSE);
  140.     if ( theErr != noErr ) {
  141.             DoOSErrorAlert("\pError re-positioning file to start of FORM", NIL);
  142.         return(FALSE);
  143.     }
  144.  
  145.     /* now look for SSND Chunk */
  146.     found = FALSE;
  147.  
  148.     while ( !found ) {
  149.         myIOParmBlk.ioBuffer = (Ptr)BaseChunkPtr;
  150.         myIOParmBlk.ioReqCount = sizeof(BaseChunk);
  151.         theErr = PBRead(&myIOParmBlk, FALSE);
  152.         if ( theErr == eofErr ) {
  153.             DoOSErrorAlert("\pError: EOF reading reading AIFF file, no SSND header", NIL);
  154.             return(FALSE);
  155.         }
  156.         if ( BaseChunk.ckID == 'SSND' ) {
  157.             found = TRUE;
  158.             myIOParmBlk.ioPosMode = fsFromMark;
  159.             myIOParmBlk.ioPosOffset = -myIOParmBlk.ioActCount;
  160.             theErr = PBSetFPos(&myIOParmBlk, FALSE);
  161.             myIOParmBlk.ioPosMode = fsAtMark;
  162.         /* get the common chunk info */
  163.             myIOParmBlk.ioBuffer = (Ptr)SoundDataHeaderPtr;
  164.             myIOParmBlk.ioReqCount = sizeof(SoundDataHeader);
  165.             theErr = PBRead(&myIOParmBlk, FALSE);
  166.         }
  167.         else {    /* skip this chunk */
  168.             myIOParmBlk.ioPosMode = fsFromMark;
  169.             myIOParmBlk.ioPosOffset = BaseChunk.ckSize;
  170.             theErr = PBSetFPos(&myIOParmBlk, FALSE);
  171.             if ( theErr == eofErr ) {
  172.                 DoOSErrorAlert("\pError reading AIFF file, no SSND header", NIL);
  173.                 return(FALSE);
  174.             }
  175.             myIOParmBlk.ioPosMode = fsAtMark;
  176.         }
  177.  
  178.     };
  179.  
  180.  
  181. /*
  182. *
  183. *
  184. *
  185. *        SoundDataHeader.ckID = BaseChunk.ckID;
  186.         SoundDataHeader.ckSize = BaseChunk.ckSize;
  187.         aLongPtr = &aLong;
  188.         myIOParmBlk.ioBuffer = (Ptr)aLongPtr;
  189.         myIOParmBlk.ioReqCount = sizeof(aLong);
  190.         theErr = PBRead(&myIOParmBlk, FALSE);
  191.         SoundDataHeader.offset = aLong;
  192.  
  193.         myIOParmBlk.ioBuffer = (Ptr)aLongPtr;
  194.         myIOParmBlk.ioReqCount = sizeof(aLong);
  195.         theErr = PBRead(&myIOParmBlk, FALSE);
  196.         SoundDataHeader.blockSize = aLong;
  197. *
  198. *
  199. */
  200.  
  201.  
  202.  
  203. /* we only get here if we have found FORM, COMM and SSND chunks */
  204.         RecLength = (long)16384;
  205.         nrec = 0;
  206.         SetProgressDialog();
  207.  
  208.  
  209.         scalefactor = 2.0/SAMPMAX;
  210.         MinSample = 0.0;
  211.         MaxSample = 0.0;
  212.         sampBufsz  = RecLength  / sizeof(int);
  213.         theIbuf = (int *)NewPtr(sizeof(int) * sampBufsz);
  214.         if ( (theErr = MemError()) != noErr ) {
  215.             DoOSErrorAlert("\pcan't get enough memory  for theIbuf", NIL);
  216.             return(FALSE);
  217.         }
  218.         SampBuf = (float *)NewPtr( sizeof(float) * sampBufsz);
  219.         if ( (theErr = MemError()) != noErr ) {
  220.             DoOSErrorAlert("\pcan't get enough memory  for SampBuf", NIL);
  221.             return(FALSE);
  222.         }
  223.  
  224.  
  225.  
  226.         bytesLeft = SoundDataHeader.ckSize - sizeof(SoundDataHeader.offset)
  227.                         - sizeof(SoundDataHeader.blockSize);
  228.  
  229.         myIOParmBlk.ioPosMode = fsAtMark;
  230.         myIOParmBlk.ioPosOffset = NIL;
  231.  
  232.         while ( bytesLeft > 0L ) {
  233.             if ( bytesLeft > RecLength )
  234.                 nBytes = RecLength;
  235.             else
  236.                 nBytes = bytesLeft;
  237.  
  238.             myIOParmBlk.ioBuffer = (Ptr)theIbuf;
  239.             myIOParmBlk.ioReqCount = nBytes;
  240.             theErr = PBRead(&myIOParmBlk, FALSE);
  241.             if (theErr != noErr ) {
  242.                 if ( theErr == eofErr )
  243.                     DoOSErrorAlert("\pEnd of file reached", NIL);
  244.             }
  245.             nBytes = myIOParmBlk.ioActCount;
  246.             if ( nBytes != myIOParmBlk.ioReqCount ) {
  247.                 DoOSErrorAlert("\pRead less bytes than expected", NIL);
  248.                 if ( nBytes == 0L ) {
  249.                     DisposPtr((Ptr)SampBuf);
  250.                     DisposPtr((Ptr)theIbuf);
  251.                     DisposeProgDialog();
  252.                     return(FALSE);
  253.                 }
  254.             }
  255.             nSamps = nBytes / sizeof(int);
  256.             for ( i = 0, Iptr = theIbuf, sp = SampBuf; i < nSamps; i++ ) {
  257.                 *sp = (*Iptr++ * scalefactor);
  258.                 if ( *sp < MinSample )
  259.                     MinSample = *sp;
  260.                 else if ( *sp > MaxSample )
  261.                     MaxSample = *sp;
  262.                 sp++;
  263.             }
  264.  
  265.     /* write it out */
  266.             NewParmBlk.ioReqCount = (long)(nSamps * sizeof(float));
  267.             NewParmBlk.ioBuffer = (Ptr)SampBuf;
  268.             if ( (theErr = PBWrite(&NewParmBlk, FALSE)) != noErr ) { 
  269.                 DoOSErrorAlert("\pError writing to sample file", NIL);
  270.             }
  271.             if ( NewParmBlk.ioActCount != (long)(nSamps * sizeof(float)) ) {
  272.                 DoOSErrorAlert("\pError writing to sample file, wrote wrong number of bytes", NIL);
  273.             }
  274.  
  275.             nrec++;
  276.             if ( !UpdateProgressDialog() ) {
  277.                 DisposPtr((Ptr)SampBuf);
  278.                 DisposPtr((Ptr)theIbuf);
  279.                 DisposeProgDialog();
  280.                 InitCursor();
  281.                 return(FALSE);
  282.             }
  283.             bytesLeft -= nBytes;
  284.         }
  285.  
  286.     DisposPtr((Ptr)SampBuf);
  287.     DisposPtr((Ptr)theIbuf);
  288.     DisposeProgDialog();
  289.     InitCursor();
  290.  
  291.  
  292. /*    if ( FormChunkHeader.ckSize > SoundDataHeader.ckSize) {
  293.         BaseChunkPtr = &BaseChunk;
  294.         myIOParmBlk.ioBuffer = (Ptr)BaseChunkPtr;
  295.         myIOParmBlk.ioReqCount = sizeof(BaseChunk);
  296.         theErr = PBRead(&myIOParmBlk, FALSE);
  297.         if ( BaseChunk.ckID == 'COMM' ) {
  298.             myIOParmBlk.ioPosMode = fsFromMark;
  299.             myIOParmBlk.ioPosOffset = -myIOParmBlk.ioActCount;
  300.             theErr = PBSetFPos(&myIOParmBlk, FALSE);
  301.  
  302.             myIOParmBlk.ioPosMode = fsAtMark;
  303.  
  304.             myIOParmBlk.ioBuffer = (Ptr)CommonHeaderPtr;
  305.             myIOParmBlk.ioReqCount = sizeof(CommonHeader);
  306.             theErr = PBRead(&myIOParmBlk, FALSE);
  307.  
  308.         }
  309.     }
  310. */
  311.  
  312.  
  313.  
  314.  
  315. /* be nosy and look at what else is in the file */
  316. /*    found = FALSE;*/
  317.  
  318.     while ( !found ) {
  319.         myIOParmBlk.ioBuffer = (Ptr)BaseChunkPtr;
  320.         myIOParmBlk.ioReqCount = sizeof(BaseChunk);
  321.         theErr = PBRead(&myIOParmBlk, FALSE);
  322.         if ( theErr == eofErr ) {
  323.             DoOSErrorAlert("\pError reading AIFF file, no SSND header", NIL);
  324.             return(FALSE);
  325.         }
  326.         /* skip this chunk */
  327.         myIOParmBlk.ioPosMode = fsFromMark;
  328.         myIOParmBlk.ioPosOffset = BaseChunk.ckSize;
  329.         theErr = PBSetFPos(&myIOParmBlk, FALSE);
  330.         if ( theErr == eofErr ) {
  331.             DoOSErrorAlert("\pError reading AIFF file, no SSND header", NIL);
  332.             return(FALSE);
  333.         }
  334.         myIOParmBlk.ioPosMode = fsAtMark;
  335.     };
  336.  
  337.     return(TRUE);
  338. }
  339.  
  340.  
  341.  
  342.  
  343.